package com.szcinda.service.dto.bankInfo;

import com.szcinda.repository.BankInfo;
import com.szcinda.repository.BankInfoRepository;
import com.szcinda.service.SnowFlakeFactory;
import org.springframework.beans.BeanUtils;
import org.springframework.data.jpa.domain.Specification;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.Assert;
import org.springframework.util.StringUtils;

import javax.persistence.criteria.Predicate;
import java.util.ArrayList;
import java.util.List;

@Service
@Transactional
public class BankInfoServiceImpl implements BankInfoService {
    private final BankInfoRepository bankInfoRepository;
    private final SnowFlakeFactory snowFlakeFactory;

    public BankInfoServiceImpl(BankInfoRepository bankInfoRepository) {
        this.bankInfoRepository = bankInfoRepository;
        this.snowFlakeFactory = SnowFlakeFactory.getInstance();
    }

    @Override
    public void create(BankInfoCreateDto createDto) {
        BankInfo bankInfo = bankInfoRepository.findByMark(createDto.getMark());
        Assert.isTrue(bankInfo == null, "存在相同唯一标注的银行账户信息记录");
        bankInfo = new BankInfo();
        BeanUtils.copyProperties(createDto, bankInfo);
        bankInfo.setId(snowFlakeFactory.nextId("BI"));
        bankInfoRepository.save(bankInfo);
    }

    @Override
    public void update(BankInfoUpdateDto updateDto) {
        BankInfo bankInfo = bankInfoRepository.findFirstById(updateDto.getId());
        BeanUtils.copyProperties(updateDto, bankInfo, "id");
        bankInfoRepository.save(bankInfo);
    }

    @Override
    public List<BankInfo> query(BankInfoQueryDto params) {
        Specification<BankInfo> specification = ((root, criteriaQuery, criteriaBuilder) -> {
            List<Predicate> predicates = new ArrayList<>();
            if (!StringUtils.isEmpty(params.getMark())) {
                Predicate site = criteriaBuilder.like(root.get("mark").as(String.class), "%" + params.getMark().trim() + "%");
                predicates.add(site);
            }
            if (!StringUtils.isEmpty(params.getRmbAccount())) {
                Predicate site = criteriaBuilder.like(root.get("rmbAccount").as(String.class), "%" + params.getRmbAccount().trim() + "%");
                predicates.add(site);
            }
            if (!StringUtils.isEmpty(params.getRmbBankName())) {
                Predicate site = criteriaBuilder.like(root.get("rmbBankName").as(String.class), "%" + params.getRmbBankName().trim() + "%");
                predicates.add(site);
            }
            if (!StringUtils.isEmpty(params.getRmbName())) {
                Predicate site = criteriaBuilder.like(root.get("rmbName").as(String.class), "%" + params.getRmbName().trim() + "%");
                predicates.add(site);
            }
            if (!StringUtils.isEmpty(params.getUsdAccount())) {
                Predicate site = criteriaBuilder.like(root.get("usdAccount").as(String.class), "%" + params.getUsdAccount().trim() + "%");
                predicates.add(site);
            }
            if (!StringUtils.isEmpty(params.getUsdName())) {
                Predicate site = criteriaBuilder.like(root.get("usdName").as(String.class), "%" + params.getUsdName().trim() + "%");
                predicates.add(site);
            }
            if (!StringUtils.isEmpty(params.getUsdBankName())) {
                Predicate site = criteriaBuilder.like(root.get("usdBankName").as(String.class), "%" + params.getUsdBankName().trim() + "%");
                predicates.add(site);
            }
            Predicate organizationId = criteriaBuilder.equal(root.get("organizationId").as(String.class), params.getOrganizationId());
            predicates.add(organizationId);
            return criteriaBuilder.and(predicates.toArray(new Predicate[0]));
        });
        return bankInfoRepository.findAll(specification);
    }

    @Override
    public void delete(String id, String userId) {
        BankInfo bankInfo = bankInfoRepository.findFirstById(id);
        bankInfoRepository.delete(bankInfo);
    }

    @Override
    public void batchCreate(List<BankInfoImportDto> importDatas, String opId, String organizationId) {
        for (BankInfoImportDto importData : importDatas) {
            BankInfo bankInfo = bankInfoRepository.findByMark(importData.getMark());
            if (bankInfo != null) {
                BeanUtils.copyProperties(importData, bankInfo, "id");
                bankInfoRepository.save(bankInfo);
            } else {
                bankInfo = new BankInfo();
                BeanUtils.copyProperties(importData, bankInfo);
                bankInfo.setId(snowFlakeFactory.nextId("BI"));
                bankInfo.setOrganizationId(organizationId);
                bankInfoRepository.save(bankInfo);
            }
        }
    }
}
